package com.briup.day25;

import com.briup.day21.Looper;
import com.briup.day21.MyCollectionImpl.MyLooper;

public class MyArrayList implements MyList {

	private Object[] data;
	
	int size = 0;  //1.i用来记录用户调用add()方法的次数  
				//2.当前已插入元素的数量,也代表新元素的索引值
	
	public final static int DEFAULT_CAPACITY = 10;
	
	//空数组常量
	private final static Object[] EMPTY_DATA = {};
	
	/*两种初始化逻辑
	 * 1.默认初始容量
	 * 2.用户自定义**/
	
	public MyArrayList() {
		//data = new Object[10];
	//	this(DEFAULT_CAPACITY); 
	//  this(0);
		data = EMPTY_DATA;
	}
	
	public MyArrayList(int capacity) {
		//capacity = capacity <= 0 ? DEFAULT_CAPACITY : capacity;
		//if (capacity <= 0) 
			//capacity = DEFAULT_CAPACITY;
		if (capacity > 0) 
			data = new Object[capacity];  //数组长度为0，初始化无意义
		else if (capacity == 0) 
			data = EMPTY_DATA;
		else 
			 throw new IllegalArgumentException("Illegal Capacity: "+
                     capacity);
			
		
	}
	
	public MyIt iterator() {   //返回一个新遍历器
		return new MyIt();
	}
	
	//使用内部类实现集合的遍历
	public class MyIt implements MyIterator{  //遍历器
		
		private int position = 0;  //用户获取元素的位置
		
		//判断是否存在下一个元素
		public boolean hasNext() {
			return position < size;
		}
		//给用户提供一个访问集合中元素的方法
		public Object next() {
			//每次返回数组中的一个元素
			return data[position++];
		}
		
	}
	
	/*
	private int position = 0;  //用户获取元素的位置
	//重置游标
	public void reset() {
		position = 0;
	}
	//判断是否存在下一个元素
	public boolean hasNext() {
		return position < size;
	}
	//给用户提供一个访问集合中元素的方法
	public Object next() {
		//每次返回数组中的一个元素
		return data[position++];
	}
	*/

	@Override
	public boolean add(Object o) {
		//先调用方法保证容量够用
		ensureCapacity();
		//把o插入到data数组中
		data[size++] = o;
		return true;
	}
	
	private void ensureCapacity() {
		//先判断数组是否已经存满，如果存满则扩容
		if(size == data.length) {
			//先创建一个比之前数组更大的数组
			int newCapacity = data.length == 0?
					DEFAULT_CAPACITY : data.length + (data.length >> 1);  // i/2 ====  i>>1
			Object[] newData = new Object[newCapacity];
			//把原数组所有元素复制到新数组的对应位置
			System.arraycopy(data, 0, newData, 0, size);
			//新数组充当data
			data = newData;
		}
	}
	
	//清空所有元素
	@Override
	public void clear() {
		// 集合对象不在保存所有元素的引用
		for (int i = 0; i < size; i++) {
			data[i] = null;
		}
		//法二
		//data = new Object[data.length];
		//size归零
		size = 0;

	}
	
	//判断集合是否包含指定元素
	@Override
	public boolean contains(Object o) {
		// 遍历整个集合，把o和每个元素进行比较
		if(o == null) {
		for (int i = 0; i < size; i++) {
			if(data[i] == null) 
				return true;
			}
		}else {
			for (int i = 0; i < size; i++) {
				if(o.equals(data[i])) 
					return true;
					
				}
			}
		
		return false;
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return size == 0;
	}

	@Override
	public boolean remove(Object o) {
		//传入的参数是要被删除的元素,并不知道是第几个
		//1.先找这个元素
		if(o == null) {
			for (int i = 0; i < size; i++) {
				if(data[i] == null)
				fastRemove(i);

			}	
		}else {
		for (int i = 0; i < size; i++) {
			if(o.equals(data[i]))
				fastRemove(i);
			}
		}
		return false;
	 
	}
	
	private void fastRemove(int i) {
		//法一：执行删除
		//data[i] = null;   //左移置空没必要
		//被删元素右边元素左移
		/*for (int j = i; j < size-1; j++) {
			data[j] = data[j+1];
		}
		*/
		
		//法二：被删元素下标为i，把data数组从下标为i+1开始的size-i-1个元素复制到下标为i的位置
		System.arraycopy(data, i+1, data, i, size-i-1);  //size-i-1不需要被位移的个数，i左边size-i个，及本身
		data[--size] = null;  //最后一位和倒数第二位元素相同，清空最后一位
	}
	
	@Override
	public int size() {
		// TODO Auto-generated method stub
		return size;
	}
	
	//临时定义 
	public void print() {
		System.out.print("[");
		for (int i = 0; i < size; i++) {
			System.out.print(data[i]);
			if(i != size - 1)
				System.out.print(",");
			
		}
		System.out.println("]");
	}

	@Override
	public Object[] toArray() {  //获取副本
		//1.
		// 返回包含此集合中所有元素的数组
		//把已经插入到集合中的元素复制一份到一个新数组
		Object[] array = new Object[size];
		System.arraycopy(data, 0, array, 0, size);
		
		return array;
		
		//2.
		//return Arrays.copyOf(data, size);
	}
	
/********************************************************************************/
	
	// 把o添加到链表中第index个位置上
	@Override
	public void add(int index, Object o) {
		if (index < 0 || index > size) {
			System.out.println("传入的索引值不合法，插入失败！");
			return ;
		}
		ensureCapacity();
		// 把从index~size-1位置上的所有元素右移一位
		System.arraycopy(data, index, data, index + 1, size - index);
					  //(原数组，开始位置，目标数组，结束位置，位移长度)
		// 把o插入到index位置
		data[index] = o;
		size++;
	}
	
	// 删除链表中index位置上的元素，返回值就是被删掉的元素
	@Override
	public Object remove(int index) {
		if (index < 0 || index >= size) {
			System.out.println("传入的索引值不合法，删除失败！");
			return null;
		}
		//位移之前，保存被删元素引用
		Object object = data[index];
		// index+1 开始到size-1的所有元素左移一位 
		System.arraycopy(data, index+1, data, index, size-index-1);
		data[--size] = null;
		return object;
	}

	// 将链表中index位置上的元素替换为o，返回的是被替换的元素
	@Override
	public Object set(int index, Object o) {
		if (index < 0 || index >= size) {
			System.out.println("传入的索引值不合法，修改失败！");
			return null;
		}
		Object object = data[index];
		data[index] = o;
		return object;
	}
	
	// 获取链表中index位置上的元素
	@Override
	public Object get(int index) {
		if (index < 0 || index >= size) {
			System.out.println("传入的索引值不合法，查找失败！");
			return null;
		}
		return data[index];
	}

}
